//
//  APIClient.swift
//  CMB250716
//
//  Created by Assistant on 2025-07-22.
//

import Foundation
import SwiftUI

/// API客户端，用于处理与后端API的网络请求
class APIClient {
    
    // MARK: - 单例
    static let shared = APIClient()
    
    // MARK: - 属性
    private var baseURL: String {
        return AppConfig.apiBaseURL + "/api"
    }
    private let session = URLSession.shared
    private var authToken: String? = nil
    
    // MARK: - 初始化
    private init() {
        // 尝试从UserDefaults获取认证令牌
        authToken = UserDefaults.standard.string(forKey: "persistentLoginToken")
    }
    
    // MARK: - 公共方法
    
    /// 设置认证令牌
    func setAuthToken(_ token: String?) {
        self.authToken = token
        
        // 保存到UserDefaults以便下次启动时使用
        if let token = token {
            UserDefaults.standard.set(token, forKey: "persistentLoginToken")
        } else {
            UserDefaults.standard.removeObject(forKey: "persistentLoginToken")
        }
    }
    
    /// 更新订单状态到后端
    /// - Parameters:
    ///   - orderId: 订单ID（后端数据库ID）
    ///   - status: 新的订单状态
    ///   - completion: 完成回调，返回成功状态和错误信息
    func updateOrderStatus(backendId: Int, status: OrderStatus, completion: @escaping (Bool, Error?) -> Void) {
        let endpoint = "/client/orders/\(backendId)/status"
        
        guard let url = URL(string: baseURL + endpoint) else {
            completion(false, NSError(domain: "APIClient", code: 400, userInfo: [NSLocalizedDescriptionKey: "无效的URL"]))
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "PUT"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        // 添加认证令牌（如果有）
        if let token = authToken {
            request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        }
        
        // 构建状态更新数据
        let statusData: [String: Any] = [
            "status": mapOrderStatusToString(status)
        ]
        
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: statusData, options: [])
        } catch {
            completion(false, error)
            return
        }
        
        if AppConfig.enableDebugLogging {
            print("[APIClient] 更新订单状态数据: \(statusData)")
        }
        
        let task = session.dataTask(with: request) { data, response, error in
            if let error = error {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 更新订单状态失败: \(error.localizedDescription)")
                }
                completion(false, error)
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse else {
                completion(false, NSError(domain: "APIClient", code: 500, userInfo: [NSLocalizedDescriptionKey: "无效的响应"]))
                return
            }
            
            if AppConfig.enableDebugLogging {
                print("[APIClient] 更新订单状态响应状态码: \(httpResponse.statusCode)")
            }
            
            if httpResponse.statusCode == 200 {
                completion(true, nil)
            } else {
                var errorMessage = "更新订单状态失败"
                if let data = data,
                   let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
                   let message = json["message"] as? String {
                    errorMessage = message
                }
                completion(false, NSError(domain: "APIClient", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: errorMessage]))
            }
        }
        
        task.resume()
    }
    
    /// 提交订单到后端
    /// - Parameters:
    ///   - order: 要提交的订单对象
    ///   - completion: 完成回调，返回成功状态和错误信息
    func submitOrder(_ order: Order, completion: @escaping (Bool, Error?, Int?) -> Void) {
        let endpoint = "/orders"
        
        guard let url = URL(string: baseURL + endpoint) else {
            completion(false, NSError(domain: "APIClient", code: 400, userInfo: [NSLocalizedDescriptionKey: "无效的URL"]), nil)
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        // 添加认证令牌（如果有）
        if let token = authToken {
            request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        }
        
        // 构建订单数据 - 匹配后端API期望的字段名
        let orderItems = order.items.compactMap { item -> [String: Any]? in
            guard let backendId = item.menuItem.backendId else {
                print("[APIClient] 警告: 菜单项 \(item.menuItem.name) 缺少后端ID")
                return nil
            }
            return [
                "menu_item_id": backendId,
                "quantity": item.quantity,
                "notes": item.specialInstructions ?? ""
            ]
        }
        
        // 注意：不要直接把 Optional 值放进字典，JSONSerialization 不支持 Optional 类型
        var orderData: [String: Any] = [
            "order_number": order.orderNumber,
            "order_type": mapDiningTypeToOrderType(order.diningType, isReservation: order.isReservation),
            "payment_method": mapPaymentMethodToString(order.paymentMethod),
            "notes": order.specialInstructions ?? "",
            "items": orderItems
        ]
        // 仅当桌号存在且可转换为 Int 时才添加
        if let tn = order.tableNumber?.trimmingCharacters(in: .whitespacesAndNewlines), !tn.isEmpty, let tnInt = Int(tn) {
            orderData["table_number"] = tnInt
        }
        
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: orderData, options: [])
        } catch {
            completion(false, error, nil)
            return
        }
        
        if AppConfig.enableDebugLogging {
            print("[APIClient] 提交订单数据: \(orderData)")
        }
        
        let task = session.dataTask(with: request) { data, response, error in
            if let error = error {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 提交订单失败: \(error.localizedDescription)")
                }
                completion(false, error, nil)
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse else {
                completion(false, NSError(domain: "APIClient", code: 500, userInfo: [NSLocalizedDescriptionKey: "无效的服务器响应"]), nil)
                return
            }
            
            if AppConfig.enableDebugLogging {
                print("[APIClient] 订单提交响应状态码: \(httpResponse.statusCode)")
            }
            
            if (200...299).contains(httpResponse.statusCode) {
                var backendOrderId: Int? = nil
                
                // 尝试解析响应体获取订单ID
                if let data = data {
                    do {
                        if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                            if let orderId = json["id"] as? Int {
                                backendOrderId = orderId
                            } else if let orderData = json["order"] as? [String: Any],
                                      let orderId = orderData["id"] as? Int {
                                backendOrderId = orderId
                            }
                        }
                    } catch {
                        if AppConfig.enableDebugLogging {
                            print("[APIClient] 解析订单响应失败: \(error.localizedDescription)")
                        }
                    }
                }
                
                if AppConfig.enableDebugLogging {
                    let bodyText = data.flatMap { String(data: $0, encoding: .utf8) } ?? "<无响应体>"
                    print("[APIClient] 订单提交成功，响应体: \(bodyText)，解析到的订单ID: \(backendOrderId ?? -1)")
                }
                completion(true, nil, backendOrderId)
            } else {
                // 打印后端返回的错误响应体，便于定位400类问题
                if AppConfig.enableDebugLogging {
                    let bodyText = data.flatMap { String(data: $0, encoding: .utf8) } ?? "<无响应体>"
                    print("[APIClient] 订单提交失败，状态码=\(httpResponse.statusCode)，响应体=\(bodyText)")
                }
                let errorMessage = "订单提交失败，状态码: \(httpResponse.statusCode)"
                completion(false, NSError(domain: "APIClient", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: errorMessage]), nil)
            }
        }
        
        task.resume()
    }
    
    /// 将PaymentMethod枚举转换为后端API期望的字符串
    private func mapPaymentMethodToString(_ paymentMethod: PaymentMethod) -> String {
        switch paymentMethod {
        case .creditCard:
            return "card"
        case .payNow:
            return "cash"
        case .applePay:
            return "apple_pay"
        case .googlePay:
            return "google_pay"
        }
    }
    
    /// 将OrderStatus枚举转换为后端API期望的status字符串
    private func mapOrderStatusToString(_ status: OrderStatus) -> String {
        switch status {
        case .pending:
            return "pending"
        case .confirmed:
            return "confirmed"
        case .preparing:
            return "preparing"
        case .ready:
            return "ready"
        case .completed:
            return "completed"
        case .cancelled:
            return "cancelled"
        }
    }
    
    /// 将DiningType枚举转换为后端API期望的order_type字符串
    private func mapDiningTypeToOrderType(_ diningType: DiningType, isReservation: Bool = false) -> String {
        if isReservation {
            switch diningType {
            case .dineIn:
                return "reservation_dine_in"
            case .takeaway:
                return "reservation_takeaway"
            }
        } else {
            switch diningType {
            case .dineIn:
                return "dine_in"
            case .takeaway:
                return "takeaway"
            }
        }
    }
    
    /// 获取菜单项列表
    /// - Parameter completion: 完成回调，返回菜单项数组或错误
    func fetchMenuItems(completion: @escaping ([MenuItem]?, Error?) -> Void) {
        let endpoint = "/menu/public/items"
        
        guard let url = URL(string: baseURL + endpoint) else {
            completion(nil, NSError(domain: "APIClient", code: 400, userInfo: [NSLocalizedDescriptionKey: "无效的URL"]))
            return
        }
        
        var request = URLRequest(url: url)
        
        // 禁用缓存以确保获取最新数据
        request.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
        
        // 添加时间戳参数防止缓存
        let timestamp = Int(Date().timeIntervalSince1970)
        if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
            urlComponents.queryItems = [URLQueryItem(name: "t", value: "\(timestamp)")]
            if let updatedURL = urlComponents.url {
                request.url = updatedURL
            }
        }
        
        // 公共API端点不需要认证令牌
        
        let task = session.dataTask(with: request) { data, response, error in
            if let error = error {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 获取菜单项失败: \(error.localizedDescription)")
                }
                completion(nil, error)
                return
            }
            
            guard let httpResponse = response as? HTTPURLResponse,
                  (200...299).contains(httpResponse.statusCode) else {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 服务器响应错误: \(String(describing: response))")
                }
                completion(nil, NSError(domain: "APIClient", code: 500, userInfo: [NSLocalizedDescriptionKey: "服务器响应错误"]))
                return
            }
            
            guard let data = data else {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 没有返回数据")
                }
                completion(nil, NSError(domain: "APIClient", code: 204, userInfo: [NSLocalizedDescriptionKey: "没有返回数据"]))
                return
            }
            
            do {
                // 解析API返回的JSON数据
                let json = try JSONSerialization.jsonObject(with: data, options: [])
                
                // 调试输出
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 菜单项API响应: \(json)")
                }
                
                // 兼容两种返回格式：
                // 1) { success: true, data: [ {...}, {...} ], message: "..." }
                // 2) { success: true, data: { items: [ {...}, {...} ] }, message: "..." }
                var itemsArray: [[String: Any]]? = nil
                
                if let responseDict = json as? [String: Any] {
                    let dataField = responseDict["data"]
                    if let arr = dataField as? [[String: Any]] {
                        // 情况1：data 直接是数组
                        itemsArray = arr
                    } else if let obj = dataField as? [String: Any] {
                        // 情况2：data 是对象，内部包含 items 数组
                        itemsArray = obj["items"] as? [[String: Any]]
                    }
                } else if let arr = json as? [[String: Any]] {
                    // 极端情况：顶层直接返回数组
                    itemsArray = arr
                }
                
                guard let itemsArray = itemsArray else {
                    if AppConfig.enableDebugLogging {
                        let dataTypeDesc: String
                        if let responseDict = json as? [String: Any] {
                            dataTypeDesc = String(describing: type(of: responseDict["data"] as Any))
                        } else {
                            dataTypeDesc = String(describing: type(of: json))
                        }
                        print("[APIClient] 响应格式不正确，期待 data 为数组或包含 items 的对象，实际 data 类型: \(dataTypeDesc)")
                    }
                    completion(nil, NSError(domain: "APIClient", code: 422, userInfo: [NSLocalizedDescriptionKey: "响应格式不正确"]))
                    return
                }
                
                // 将API数据转换为MenuItem对象
                var menuItems: [MenuItem] = []
                var availableCount = 0
                var unavailableCount = 0
                
                for itemDict in itemsArray {
                    if let menuItem = self.parseMenuItem(from: itemDict) {
                        menuItems.append(menuItem)
                        if menuItem.isAvailable {
                            availableCount += 1
                        } else {
                            unavailableCount += 1
                        }
                        if AppConfig.enableDebugLogging {
                            let id = itemDict["id"] ?? "-"
                            let catId = itemDict["category_id"] ?? "-"
                            let isAvail = itemDict["is_available"] ?? "-"
                            print("[APIClient] item id=\(id) name=\(menuItem.name) is_available=\(isAvail) category_id=\(catId)")
                        }
                    } else if AppConfig.enableDebugLogging {
                        print("[APIClient] 跳过无法解析的菜单项: \(itemDict)")
                    }
                }
                
                if AppConfig.enableDebugLogging {
                    print("[APIClient] 成功解析 \(menuItems.count) 个菜单项，可售: \(availableCount)，售罄: \(unavailableCount)")
                }
                completion(menuItems, nil)
                
            } catch {
                if AppConfig.enableDebugLogging {
                    print("[APIClient] JSON解析错误: \(error.localizedDescription)")
                }
                completion(nil, error)
            }
        }
        
        task.resume()
    }
    
    // MARK: - 私有方法
    
    /// 从API响应数据解析MenuItem对象
    /// - Parameter dict: API返回的菜单项字典
    /// - Returns: 解析后的MenuItem对象，如果解析失败则返回nil
    private func parseMenuItem(from dict: [String: Any]) -> MenuItem? {
        // 仅要求名称字段存在
        guard let name = dict["name"] as? String else {
            if AppConfig.enableDebugLogging {
                print("[APIClient] 菜单项缺少必要字段: name")
            }
            return nil
        }
        
        // 获取英文名称，如果不存在则使用中文名称
        let englishName = dict["name_en"] as? String ?? name
        
        // 获取描述
        let description = dict["description"] as? String ?? ""
        let englishDescription = dict["description_en"] as? String ?? ""
        
        // 获取价格
        // 后端可能返回整型或浮点型，统一转为 Double
        var price: Double = 0.0
        if let p = dict["price"] as? Double {
            price = p
        } else if let p = dict["price"] as? Int {
            price = Double(p)
        } else if let p = dict["price"] as? String, let dp = Double(p) {
            price = dp
        }
        
        // 获取分类
        var category: MenuCategory = .main
        if let categoryId = dict["category_id"] as? Int {
            switch categoryId {
            case 1: category = .promotion
            case 2: category = .recommended
            case 3: category = .combo
            case 4: category = .main
            case 5: category = .side
            case 6: category = .drinks
            case 7: category = .desserts
            default: category = .main
            }
        }
        
        // 获取图片URL
        let imageURL = dict["image_url"] as? String
        
        // 获取是否可用
        let isAvailable = dict["is_available"] as? Bool ?? true
        
        // 获取后端ID
        let backendId = dict["id"] as? Int
        
        // 创建MenuItem对象（使用本地生成的UUID）
        let menuItem = MenuItem(
            name: name,
            englishName: englishName,
            description: description,
            englishDescription: englishDescription,
            price: price,
            category: category,
            imageName: "", // 本地图片名称为空
            realImageName: "", // 本地图片名称为空
            imageURL: imageURL, // 使用API返回的图片URL
            isAvailable: isAvailable,
            ingredients: [],
            availableMeatTypes: [],
            isSpicy: false,
            isVegetarian: false,
            backendId: backendId // 保存后端ID
        )
        
        return menuItem
    }
}